package com.best.oasis.settlement.service.methodTimeAdvice;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.best.oasis.settlement.util.SecurityUtil;



public class MethodTimeAdvice implements MethodInterceptor {  
    protected final Log log = LogFactory.getLog("actionInfoFile");  
    private final String delimiter=",";
    private final String headPrefix="[StartTime Operator Time(ms) Memory(kb) Method Class],";
    private SimpleDateFormat formator = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**   
     * 拦截要执行的目标方法   
     */    
    @SuppressWarnings("rawtypes")
	public Object invoke(MethodInvocation invocation) throws Throwable {     
        //用 commons-lang 提供的 StopWatch 计时，Spring 也提供了一个 StopWatch
    	StringBuilder sb = new StringBuilder();
        StopWatch clock = new StopWatch(); 
        
		sb.append( headPrefix );
		sb.append( formator.format(new Date()) + delimiter );
		clock.start(); // 计时开始
		
		//记录方法调用前的空闲内存
		long startFreeMemory = Runtime.getRuntime().freeMemory();
		
		Object result = invocation.proceed();
		
		//记录方法调用后的空闲内存
		long endFreeMemory = Runtime.getRuntime().freeMemory();
		long usedMemory = getUsedMemory(startFreeMemory, endFreeMemory);
		
		clock.stop(); // 计时结束
        String usrname = SecurityUtil.getLoginUsername()+ "_" + SecurityUtil.getLoginUserNick();
        //方法参数类型，转换成简单类型     
        Class[] params = invocation.getMethod().getParameterTypes();     
        String[] simpleParams = new String[params.length];     
        for (int i = 0; i < params.length; i++) {     
            simpleParams[i] = params[i].getSimpleName();     
        }     
        sb.append( usrname + delimiter );
        sb.append( clock.getTime() + delimiter);
        sb.append(' ');
        sb.append( usedMemory + delimiter);
        sb.append( invocation.getMethod().getName()+ delimiter );
        sb.append( invocation.getThis().getClass().getName() );
        log.info(sb.toString());
        return result;     
    }       
    /**
     * 计算使用的内存
     * @param startFreeMemory 起始时使用内存
     * @param endFreeMemory 结束时使用内存
     * @return 返回使用的内存（单位：kb）
     */
    private long getUsedMemory(long startFreeMemory, long endFreeMemory){
    	long result = 0;
    	long diff = startFreeMemory - endFreeMemory;
    	result = diff/1024;
    	return result;
    }
  
}  
